fix: keep refreshing after markets close - #22
Merged
Conversation
Timer refreshes were skipped whenever no watchlist session was active, but that gate read the marketState cached by the last fetch and only a fetch could update it. The first closed session latched the app off for the rest of its life: it never saw the market reopen, so the menu bar kept showing a price from hours or days earlier until TickerBar was relaunched. Replace the repeating timer plus skip-gate with a one-shot timer that re-arms itself after every fetch. A closed market now only stretches the cadence to 15 minutes, so marketState is always re-read and a reopening, holiday or half-day is always noticed. Refresh on wake, top up a stale panel as the watchlist appears, and retry a failed fetch after 5, 15 and 60 seconds before falling back to the cadence. Both timers move to the common run loop modes so they keep ticking while the panel is open, and both carry a tolerance so macOS can coalesce their wakeups.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
Reported symptom: the menu bar showed a price from yesterday at 3pm.
Evidence from the live 1.5.0 install:
Sat Aug 15 15:05:51— a Saturday, US markets shutrotationSpeed30— and the status item repainted at exactly:15/:45, every 30 sThe rotation timer had survived all 44 sleep/wake cycles, so this was never a dead timer. The refresh timer was firing every 60 s and returning immediately:
anyMarketActiveis derived from the cachedmarketState, and only a fetch can updatemarketState— so the gate blocked the one thing that could clear it. The first closed session latched refreshes off for the rest of the process lifetime. It would not have resumed when the US market reopened on Monday.This fires every single day, not just at weekends: once Yahoo moves from
POSTPOSTtoCLOSED, TickerBar is frozen until it is relaunched.The fix
A closed market must slow the cadence, never stop it. The repeating timer plus skip-gate becomes a one-shot timer that re-arms itself after every fetch, so the cadence always reflects the state the last fetch actually observed and
marketStateis always re-read.max(interval, 15 min). 96 fetches a day, and a reopening, holiday or half-day is picked up within 15 minutes with no relaunch.Also fixed, since "always refreshing" needs them:
NSWorkspace.didWakeNotificationand re-anchors the cadence, instead of showing pre-sleep prices until the next tick..commonrun loop modes, so a refresh still lands while the panel is open — the menu-tracking run loop does not service.default-only timers.tolerance, letting macOS coalesce their wakeups with other timers instead of waking the CPU alone. Correctness comes from re-arming after each fetch, not from firing on an exact second.Verification
SRAD $13.82 +1.3%) — under 1.5.0 the same state was the frozen one.